﻿using BDRUtils.Utility;
using System;

namespace BDRUtils.Extensions
{
    /// <summary>
    /// 对象拓展
    /// </summary>
    public static class ObjectExtensions
    {
        /// <summary>
        /// 检查对象是否为null 或者 empty
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static bool IsNull(this object obj)
        {
            return obj == null || obj.ToString() == string.Empty;
        }

        /// <summary>
        /// 检查对象是否不等于null并且empty
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static bool IsNotNull(this object obj)
        {
            return obj != null && obj.ToString().Trim() != string.Empty;
        }

        /// <summary>
        /// 转非空字符串
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static string NullToString(this object obj)
        {
            return obj == null ? string.Empty : obj.ToString();
        }

        /// <summary>
        /// 转换为Guid
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static Guid ToGuid(this object val)
        {
            _ = Guid.TryParse(val.NullToString(), out Guid result);
            return result;
        }

        /// <summary>
        /// 尝试Convert to int32
        /// </summary>
        /// <param name="val"></param>
        /// <returns></returns>
        public static int ToInt32(this object val)
        {
            int result = 0;
            try
            {
                if (val != null)
                    result = Convert.ToInt32(val);
            }
            catch
            {
                result = 0;
            }
            return result;
        }

        /// <summary>
        /// 尝试int.TryParse
        /// </summary>
        /// <param name="val"></param>
        /// <param name="result"></param>
        /// <returns></returns>
        public static bool ToInt32(this object val, out int result)
        {
            bool sucess = int.TryParse(val.NullToString(), out result);
            return sucess;
        }

        /// <summary>
        /// 转化为decimal类型
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static decimal ToDecimal(this object obj)
        {
            bool s = decimal.TryParse(obj.NullToString(), out var result);
            return result;
        }

        /// <summary>
        /// 转化为decimal类型
        /// </summary>
        /// <param name="obj">obj</param>
        /// <param name="decimals">保留多少位小数</param>
        /// <returns></returns>
        public static decimal ToDecimal(this object obj, int decimals)
        {
            _ = decimal.TryParse(obj.NullToString(), out var result);
            result = decimal.Round(result, decimals);
            return result;
        }

        /// <summary>
        /// 判断是否为数字
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static bool IsNumeric(this object value)
        {
            try
            {
                _ = Convert.ToInt32(value.NullToString());
                return true;
            }
            catch (FormatException)
            {
                return false;
            }
        }

        /// <summary>
        /// 如小数保留2位，整数直接取整
        /// </summary>
        /// <param name="data">需转换值</param>
        /// <returns></returns>
        public static string RoundToString(this decimal data)
        {
            int result = (int)data;
            if (data == result)
            {
                return result.ToString();
            }
            return data.ToString("#0.00");
        }

        /// <summary>
        /// 将当前对象的属性值复制到目标对象，使用浅表复制
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static T CopyTo<T>(this object obj) where T : class
        {
            var target = Activator.CreateInstance<T>();
            if (obj == null)
                return target;

            EntityProvider.GetCast(obj.GetType(), typeof(T)).Cast(obj, target);
            return target;
        }

        /// <summary>
        /// 将当前对象的属性值复制到目标对象，使用浅表复制
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <typeparam name="D"></typeparam>
        /// <param name="obj"></param>
        /// <param name="target"></param>
        /// <returns></returns>
        public static void CopyTo<D, T>(this D obj, T target) where T : class where D : class
        {
            EntityProvider.GetCast(obj.GetType(), typeof(T)).Cast(obj, target);
        }

        /// <summary>
        /// 将当前对象的属性值复制到目标对象，使用浅表复制
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <typeparam name="D"></typeparam>
        /// <param name="obj"></param>
        /// <param name="action">此方法委托可作对象的转化后进一步的初始化工作</param>
        /// <returns></returns>
        public static T CopyTo<D, T>(this D obj, Action<T> action) where T : class where D : class
        {
            if (obj == null)
                return null;
            var target = CopyTo<T>(obj);
            action(target);
            return target;
        }
    }
}
